package com.tju.ocean_ecology_website.controller;

import com.tju.ocean_ecology_website.config.FileUploadConfig;
import com.tju.ocean_ecology_website.dto.ApiResponse;
import com.tju.ocean_ecology_website.dto.PageResult;
import com.tju.ocean_ecology_website.entity.FileUpload;
import com.tju.ocean_ecology_website.security.JwtTokenUtil;
import com.tju.ocean_ecology_website.service.FileUploadService;
import com.tju.ocean_ecology_website.service.UserService;
import com.tju.ocean_ecology_website.util.FileUploadUtil;
import com.tju.ocean_ecology_website.mapper.UserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 文件上传控制器
 *
 * @author shaolong
 * @since 2025-05-10 10:00:00
 */
@RestController
@RequestMapping("/api/upload")
public class FileUploadController {

    private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);

    @Autowired
    private FileUploadService fileUploadService;

    @Autowired
    private UserService userService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private FileUploadConfig fileUploadConfig;

    @Autowired
    private UserMapper userMapper;

    /**
     * 上传图片并更新业务表
     *
     * 当提供targetId参数时，会自动更新相应业务表中的图片URL字段。
     * 支持的业务表和字段如下：
     * - avatar: 更新user表的avatar字段
     * - activity/project: 更新activity表的image字段
     * - logo: 更新organization_info表的logo字段
     * - news: 更新news表的cover_image字段
     * - education: 更新education_resource表的cover_image字段
     *
     * @param file 文件对象
     * @param type 图片类型（avatar/activity/project/banner/logo/news/education等）
     * @param targetId 目标记录ID，如用户ID、活动ID等，可选
     * @return 上传结果
     */
    @PostMapping("/image/{type}")
    public ResponseEntity<ApiResponse<Map<String, Object>>> uploadImage(
            @RequestParam("file") MultipartFile file,
            @PathVariable("type") String type,
            @RequestParam(value = "targetId", required = false) Long targetId) {

        try {
            // 获取当前用户ID
            Long userId = getCurrentUserId();
            if (userId == null) {
                return ResponseEntity.badRequest().body(ApiResponse.error(401, "未登录或登录已过期"));
            }

            // 验证上传类型
            validateUploadType(type);

            Map<String, Object> result;
            FileUpload fileUpload;
            boolean updateResult = false;

            // 如果提供了targetId，则上传文件并更新业务表
            if (targetId != null) {
                result = fileUploadService.uploadFileAndUpdateBusiness(file, type, targetId, userId);
                fileUpload = (FileUpload) result.get("fileUpload");
                updateResult = (boolean) result.get("updateBusiness");
            } else {
                // 如果没有提供targetId，只上传文件
                fileUpload = fileUploadService.uploadFile(file, type, userId);
            }

            // 构建响应数据
            Map<String, Object> data = new HashMap<>();
            data.put("id", fileUpload.getId());
            data.put("originalName", fileUpload.getOriginalName());
            data.put("fileName", fileUpload.getFileName());
            data.put("fileUrl", fileUpload.getFileUrl());
            data.put("fileSize", fileUpload.getFileSize());
            data.put("fileType", fileUpload.getFileType());
            data.put("uploadType", fileUpload.getUploadType());
            data.put("createTime", fileUpload.getCreateTime());

            String message;
            if (targetId != null) {
                data.put("updateBusiness", updateResult);
                message = updateResult ? "上传成功并更新业务表" : "上传成功，但更新业务表失败";
            } else {
                message = "上传成功";
            }

            return ResponseEntity.ok(ApiResponse.success(data, message));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, e.getMessage()));
        } catch (IOException e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(500, "文件上传失败: " + e.getMessage()));
        } catch (Exception e) {
            logger.error("上传图片失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(500, "服务器错误: " + e.getMessage()));
        }
    }

    /**
     * 获取当前用户ID
     *
     * @return 用户ID
     */
    private Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            return userMapper.findByUsername(userDetails.getUsername()).getId();
        }
        return null;
    }

    /**
     * 获取文件列表
     *
     * @param type 文件类型
     * @param page 页码
     * @param size 每页数量
     * @return 文件列表
     */
    @GetMapping("/files/{type}")
    public ResponseEntity<ApiResponse<PageResult<FileUpload>>> getFiles(
            @PathVariable("type") String type,
            @RequestParam(value = "page", defaultValue = "0") int page,
            @RequestParam(value = "size", defaultValue = "10") int size) {

        try {
            // 获取当前用户ID
            Long userId = getCurrentUserId();
            if (userId == null) {
                return ResponseEntity.badRequest().body(ApiResponse.error(401, "未登录或登录已过期"));
            }

            // 验证上传类型
            validateUploadType(type);

            // 查询文件列表
            Page<FileUpload> fileUploads = fileUploadService.queryByTypeAndUserId(type, userId, PageRequest.of(page, size));

            // 构建响应数据
            PageResult<FileUpload> pageResult = new PageResult<>();
            pageResult.setList(fileUploads.getContent());
            pageResult.setTotal(fileUploads.getTotalElements());
            pageResult.setPage(page);
            pageResult.setPageSize(size);

            return ResponseEntity.ok(ApiResponse.success(pageResult, "获取文件列表成功"));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, e.getMessage()));
        } catch (Exception e) {
            logger.error("获取文件列表失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(500, "服务器错误: " + e.getMessage()));
        }
    }

    /**
     * 删除文件
     *
     * @param id 文件ID
     * @return 删除结果
     */
    @DeleteMapping("/files/{id}")
    public ResponseEntity<ApiResponse<Boolean>> deleteFile(@PathVariable("id") Long id) {
        try {
            // 获取当前用户ID
            Long userId = getCurrentUserId();
            if (userId == null) {
                return ResponseEntity.badRequest().body(ApiResponse.error(401, "未登录或登录已过期"));
            }

            // 查询文件信息
            FileUpload fileUpload = fileUploadService.queryById(id);
            if (fileUpload == null) {
                return ResponseEntity.badRequest().body(ApiResponse.error(404, "文件不存在"));
            }

            // 验证文件所有权
            if (!fileUpload.getUserId().equals(userId)) {
                return ResponseEntity.badRequest().body(ApiResponse.error(403, "无权删除该文件"));
            }

            // 删除文件
            boolean result = fileUploadService.deleteById(id);

            return ResponseEntity.ok(ApiResponse.success(result, "删除文件成功"));
        } catch (Exception e) {
            logger.error("删除文件失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(500, "服务器错误: " + e.getMessage()));
        }
    }

    /**
     * 获取支持的上传类型
     *
     * @return 支持的上传类型
     */
    @GetMapping("/types")
    public ResponseEntity<ApiResponse<List<String>>> getUploadTypes() {
        try {
            // 允许的上传类型
            String[] allowedTypes = {"avatar", "activity", "project", "banner", "logo", "news", "education"};
            List<String> types = Arrays.asList(allowedTypes);

            return ResponseEntity.ok(ApiResponse.success(types, "获取上传类型成功"));
        } catch (Exception e) {
            logger.error("获取上传类型失败", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(500, "服务器错误: " + e.getMessage()));
        }
    }

    /**
     * 验证上传类型
     *
     * @param type 上传类型
     */
    private void validateUploadType(String type) {
        // 允许的上传类型
        String[] allowedTypes = {"avatar", "activity", "project", "banner", "logo", "news", "education"};
        boolean isValid = false;
        for (String allowedType : allowedTypes) {
            if (allowedType.equals(type)) {
                isValid = true;
                break;
            }
        }
        if (!isValid) {
            throw new IllegalArgumentException("不支持的上传类型: " + type);
        }
    }
}
